package com.ivo.quartz;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ivo.biz.ActualCapacityOfMon;
import com.ivo.biz.AryPerformanceManager;
import com.ivo.biz.LcmPerformanceManager;
import com.ivo.biz.Performance;
import com.ivo.biz.PerformanceDay;
import com.ivo.biz.PerformanceMon;
import com.ivo.biz.PerformanceService;
import com.ivo.biz.StandardCapacityOfMon;
import com.ivo.core.hibernate.HibernateInvoker;
import com.ivo.util.DateUtil;
import com.ivo.util.StringUtil;



@Repository
public class AryPerformanceQuartz {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
 	private HibernateInvoker hibernateInvoker;
	 
    @Autowired
    private PerformanceService performanceService;
	
    @Autowired
    private AryPerformanceManager aryPerformanceManager;
    
    @Transactional
    @Scheduled(cron = "0 0 11 16 * ? ")
	public void execute() {
    	
		
		SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance(); 
		
		String str = sdf.format(calendar.getTime());
		String month = str.substring(0, 7);
//		String month ="2017-09";
				
		calendar.add(Calendar.MONTH, -1);       
		String str1 = sdf.format(calendar.getTime());
		String lastmonth = str1.substring(0, 7);
		
		double attendance = 0.0;
		double worktype = 0.0;
		double workability = 30.0;
		double compatibility = 30.0;
		List<PerformanceMon> list = hibernateInvoker.find(PerformanceMon.class, "from PerformanceMon p where p.factory = 'ARY' and p.month = '" + month + "'");
		for(PerformanceMon objPerformanceMon:list){
			if(objPerformanceMon.getOpe_fk() == null)continue;
			String emp_id = objPerformanceMon.getEmp_id();
			Performance objPerformanceExist = performanceService.getPerformance(month,emp_id);
			if(objPerformanceExist==null){
				Performance objPerformance =new Performance();
				objPerformance.setMonth(month);
				objPerformance.setFactory(objPerformanceMon.getFactory());
				objPerformance.setEmp_id(objPerformanceMon.getEmp_id());
				objPerformance.setEmp_name(objPerformanceMon.getEmp_name());
				objPerformance.setGender(objPerformanceMon.getGender());
				objPerformance.setOpe_fk(objPerformanceMon.getOpe_fk());
				if(StringUtil.isEmpty(objPerformanceMon.getClassType())){
					objPerformance.setClassType("");
				}else{
					objPerformance.setClassType(objPerformanceMon.getClassType());
				}
				
				//logger.info("检测是否有失责");
				if(getMajorLoss(objPerformanceMon, month, lastmonth)){
					objPerformance.setAttendance(0.0);
					objPerformance.setWorktype(0.0);
					objPerformance.setWorkability(0.0);
					objPerformance.setCompatibility(0.0);
				}else{
					//logger.info("考勤得分计算");
					attendance = CalculateAttendance(objPerformanceMon,month);
					
					//logger.info("工种得分计算");
					worktype = CalculateWorktype(objPerformanceMon, month);
					
					//logger.info("工作能力得分计算");
					workability = objPerformanceMon.getWorkAbility() == null ? 0:objPerformanceMon.getWorkAbility();
					
					//logger.info("配合度得分计算");
					compatibility = objPerformanceMon.getCompatibility() == null ? 0:objPerformanceMon.getCompatibility();
					
					objPerformance.setAttendance(attendance);
					objPerformance.setWorktype(worktype);
					objPerformance.setWorkability(workability);
					objPerformance.setCompatibility(compatibility);
				}
				
				aryPerformanceManager.save(objPerformance);
			}else{
					if(getMajorLoss(objPerformanceMon, month, lastmonth)){
						objPerformanceExist.setAttendance(0.0);
						objPerformanceExist.setWorktype(0.0);
						objPerformanceExist.setWorkability(0.0);
						objPerformanceExist.setCompatibility(0.0);
					}else{
						//logger.info("考勤得分计算");
						attendance = CalculateAttendance(objPerformanceMon,month);
						
						//logger.info("工种得分计算");
						worktype = CalculateWorktype(objPerformanceMon, month);
						
						//logger.info("工作能力得分计算");
						workability = objPerformanceMon.getWorkAbility() == null ? 0:objPerformanceMon.getWorkAbility();
						
						//logger.info("配合度得分计算");
						compatibility = objPerformanceMon.getCompatibility() == null ? 0:objPerformanceMon.getCompatibility();
						
						objPerformanceExist.setAttendance(attendance);
						objPerformanceExist.setWorktype(worktype);
						objPerformanceExist.setWorkability(workability);
						objPerformanceExist.setCompatibility(compatibility);
					}
					aryPerformanceManager.save(objPerformanceExist);
				}
				
				
			}
		
		
		
		
		logger.info("核算得分结束!");
	}
    
    @Transactional
    @Scheduled(cron = "0 30 11 16 * ? ")
    public void Calculate(){
    	
    	String month = DateUtil.formatDate(new Date()).substring(0, 7);
    	List<Performance> list = hibernateInvoker.find(Performance.class,"from Performance p where p.month = '" + month + "'and p.factory = 'ARY' and p.isValid is true");
    	for(Performance p : list){
    		double score = 0.0;
    		if(p.getAttendance() != null){
    			score = score + p.getAttendance();
    		}
    		if(p.getWorktype() != null){
    			score = score + p.getWorktype();
    		}
    		if(p.getWorkability() != null){
    			score = score + p.getWorkability();
    		}
    		if(p.getCompatibility() != null){
    			score = score + p.getCompatibility();
    		}
    		p.setScore(score);
    		aryPerformanceManager.save(p);
    	}
    	logger.info("Hello!");
    }
	
    
    @Transactional
    @Scheduled(cron = "0 40 11 16 * ? ")
    public void CalculateBonus(){
    	
    	String month = DateUtil.formatDate(new Date()).substring(0, 7);
    	List<Performance> list = hibernateInvoker.find(Performance.class,"from Performance p where p.month = '" + month + "'and p.factory = 'ARY' and p.isValid is true order by p.score desc,p.compatibility desc,p.workability desc,p.worktype desc,p.attendance desc ");
    	
    	int A = (int)Math.floor(list.size() * 0.07);
    	int B = (int)Math.floor(list.size() * 0.10);
    	int C = (int)Math.floor(list.size() * 0.13);
    	int D = (int)Math.floor(list.size() * 0.16);
    	int E = (int)Math.floor(list.size() * 0.14);
    	int F = (int)Math.floor(list.size() * 0.17);
    	int G = (int)Math.floor(list.size() * 0.12);
    	int H = (int)Math.floor(list.size() * 0.08);
    	int I = (int)Math.floor(list.size() * 0.03);
    	int total = A+B+C+D+E+F+G+H+I;
    	E = list.size() - total + E;
    	total = A +B+C+D+E+F+G+H+I;
    	 
    	for(int i = 0; i < list.size(); i++){
    		if(i < A){
    			list.get(i).setBonus(200.0);
    			list.get(i).setGrade("A");
    		}else if(i >= A && i < A + B){
    			list.get(i).setBonus(170.0);
    			list.get(i).setGrade("B");
    		}else if(i >= A + B && i <  A + B + C){
    			list.get(i).setBonus(140.0);
    			list.get(i).setGrade("C");
    		}else if(i >= A + B + C && i < A + B + C + D){
    			list.get(i).setBonus(110.0);
    			list.get(i).setGrade("D");
    		}else if(i >= A + B + C + D && i < A + B + C + D + E){
    			list.get(i).setBonus(95.0);
    			list.get(i).setGrade("E");
    		}else if(i >= A + B + C + D + E && i < A + B + C + D + E + F){
    			list.get(i).setBonus(80.0);
    			list.get(i).setGrade("F");
    		}else if(i >= A + B + C + D + E + F && i < A + B + C + D + E + F + G){
    			list.get(i).setBonus(40.0);
    			list.get(i).setGrade("G");
    		}else if(i >= A + B + C + D + E + F + G && i < A + B + C + D + E + F + G + H){
    			list.get(i).setBonus(15.0);
    			list.get(i).setGrade("H");
    		}else if(i >= A + B + C + D + E + F + G + H && i < A + B + C + D + E + F + G + H + I){
    			list.get(i).setBonus(0.0);
    			list.get(i).setGrade("I");
    		}
    		aryPerformanceManager.save(list.get(i));
    	}
    	
    	logger.info("Hello!");
    }
    
    
    
	public double CalculateAttendance(PerformanceMon objPerformanceMon, String month){
		double attendance = 0.0;
		Double shfthour = objPerformanceMon.getShftHour();
		Double attdhour = objPerformanceMon.getAttdHour();
		BigDecimal shfthour1 = new BigDecimal(shfthour);
		BigDecimal attdhour1 = new BigDecimal(attdhour);
		BigDecimal diffhour = shfthour1.subtract(attdhour1);//差异时数=应出勤-实际出勤
		int i = diffhour.compareTo(BigDecimal.ZERO);  //i = 差异时数-0
		if(i<0){
			Double s= diffhour.divide(new BigDecimal(10), 0,BigDecimal.ROUND_HALF_UP).doubleValue();
			attendance = 10.0 + Math.abs(s);
		}
		else if (i>0){ 
			Double s= diffhour.divide(new BigDecimal(8), 0,BigDecimal.ROUND_HALF_UP).doubleValue();
			attendance = 10.0 - Math.abs(s);
		}
		else if (i==0){
			attendance = 10.0;
		}
		if(attendance>20) attendance=20.0;
		if(attendance<0)  attendance=0.0;
		return attendance;
	}
	
	public double CalculateWorktype(PerformanceMon objPerformanceMon, String month){
		double worktype = 0.0;
		if(objPerformanceMon.getWorkType() != null){
			if(objPerformanceMon.getWorkType() == 316){
				worktype = 20.0;
			}else if(objPerformanceMon.getWorkType() == 315){
				worktype = 18.0;
			}else if(objPerformanceMon.getWorkType() == 314){
				worktype = 15.0;
			}else if(objPerformanceMon.getWorkType() == 313){
				worktype = 12.0;
			}
		}
		return worktype;
	}
	
	public boolean getMajorLoss(PerformanceMon objPerformanceMon, String month, String lastmonth){
		boolean flag = false;
		String hql = "from PerformanceDay pd where pd.fab_date >= '" + lastmonth + "-16' and pd.fab_date <= '" + month + "-15' and pd.emp_id = '" + objPerformanceMon.getEmp_id() + "' and pd.isValid = true";
		List <PerformanceDay> list = hibernateInvoker.find(PerformanceDay.class, hql);
		if(list.size() != 0){
			flag = true;
		}
		return flag;
	}
	
	public double CalculateQuality(PerformanceMon objPerformanceMon, double totalScore, String month){
		String from ="";
		String to = month + "-15";
		SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance(); 
		calendar.add(Calendar.MONTH, -1);   
		String str1 = sdf.format(calendar.getTime());
		from = str1.substring(0, 7) + "-16";
		List<PerformanceDay> performanceday = hibernateInvoker.find(PerformanceDay.class, "from PerformanceDay p where p.emp_id = '" + objPerformanceMon.getEmp_id() + "' and p.fab_date >= '" + from + "' and p.fab_date <= '" + to + "'");
		if(performanceday.size() == 0){
			return totalScore;
		}else{
			for(PerformanceDay per : performanceday){
				if(per.getType() == 31 || per.getType() == 32 || per.getType() == 33){
					return 0.0;
				}
			}
		}
		return 0.0;
	}
	
	public double CalculateDPPM(PerformanceMon objPerformanceMon, double totalScore, String month){
		List<PerformanceDay> performanceday = hibernateInvoker.find(PerformanceDay.class, "from PerformanceDay p where p.emp_id = '" + objPerformanceMon.getEmp_id() + "' and p.fab_date = '" + month + "' and p.type = '34'" );
		if(performanceday.size() == 0){
			return totalScore;
		}else{
			if(performanceday.size() == 1)return 5.0;
			if(performanceday.size() >= 1)return 0.0;
		}
		return 0.0;
	}
}
